package com.hand.wfive.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

import androidx.annotation.Nullable;

import com.hand.wfive.App;
import com.hand.wfive.R;

public class StampView extends View {

    private int mCenterX, mCenterY, mRadius, mAlpha = 255, mColor = Color.RED, mRotate = 0,
            mBigOvalWidth = 4;

    private int mTextSizeTop = 36, mTextSizeCentre = 24, mTextSizeBottom = 36,
            mTextMarginTop = 0, mTextMarginCentre = 0, mTextMarginBottom = 0,
            mTextSpanTop = 0, mTextSpanCentre = 0, mTextSpanBottom = 0;

    private float mTempR;

    private String mTextTop, mTextCentre, mTextBottom;

    private boolean mShowTitleTop = true, mShowTitleCentre = true, mShowTitleBottom = true,
            mShowStar = true;

    private Path mPathString;
    private RectF mRectF;
    private Paint mPaint;

    public StampView(Context context) {
        super(context);
        init(context, null);
    }

    public StampView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public StampView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        if (attrs != null) {
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.StampView);
            mColor = typedArray.getColor(R.styleable.StampView_stamp_color, mColor);
            mRotate = typedArray.getInt(R.styleable.StampView_stamp_rotate, 0);

            mTextSizeTop = typedArray.getDimensionPixelSize(R.styleable.StampView_stamp_textSizeTop, mTextSizeTop);
            mTextSizeCentre = typedArray.getDimensionPixelSize(R.styleable.StampView_stamp_textSizeCentre, mTextSizeCentre);
            mTextSizeBottom = typedArray.getDimensionPixelSize(R.styleable.StampView_stamp_textSizeBottom, mTextSizeBottom);
            mTextMarginTop = typedArray.getDimensionPixelSize(R.styleable.StampView_stamp_textMarginTop, mTextMarginTop);
            mTextMarginCentre = typedArray.getDimensionPixelSize(R.styleable.StampView_stamp_textMarginCentre, mTextMarginCentre);
            mTextMarginBottom = typedArray.getDimensionPixelSize(R.styleable.StampView_stamp_textMarginBottom, mTextMarginBottom);
            mTextSpanTop = typedArray.getDimensionPixelSize(R.styleable.StampView_stamp_textSpanTop, mTextSpanTop);
            mTextSpanCentre = typedArray.getDimensionPixelSize(R.styleable.StampView_stamp_textSpanCentre, mTextSpanCentre);
            mTextSpanBottom = typedArray.getDimensionPixelSize(R.styleable.StampView_stamp_textSpanBottom, mTextSpanBottom);

            mTextTop = typedArray.getString(R.styleable.StampView_stamp_textTop);
            mTextCentre = typedArray.getString(R.styleable.StampView_stamp_textCentre);
            mTextBottom = typedArray.getString(R.styleable.StampView_stamp_textBottom);

            typedArray.recycle();
        }

        mPathString = new Path();
        mRectF = new RectF();
        mPaint = new Paint();
        mPaint.setDither(true);
        mPaint.setAntiAlias(true);

        mTempR = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                300, context.getResources().getDisplayMetrics()) / 3f;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mCenterX = w / 2;
        mCenterY = h / 2;
        mRadius = w / 3;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.save();
        canvas.rotate(mRotate, mCenterX, mCenterY);
        mPaint.setColor(mColor);
        mPaint.setAlpha(mAlpha);

        // 绘制外围大圆
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(mBigOvalWidth * (mRadius / mTempR));
        canvas.drawCircle(mCenterX, mCenterY, mRadius, mPaint);

        //绘制五角星
        float width = mRadius * 3;
        float outR = width / 2 / 5;
        if (mShowStar) {
            float inR = outR * sin(18) / sin(180 - 36 - 18);
            mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
            Path path = getStarPath(outR, inR);
            canvas.save();
            canvas.translate(mCenterX, mCenterY);
            canvas.rotate(-18);
            canvas.drawPath(path, mPaint);
            canvas.restore();
        }
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setTypeface(App.getContext().getSongTypeface());
        // 绘制上半部分字符
        if (mShowTitleTop && !TextUtils.isEmpty(mTextTop)) {
            mPaint.setTextSize(mTextSizeTop * (mRadius / mTempR));
            mPaint.setLetterSpacing(mTextSpanTop);
            float textWidth = mPaint.measureText(mTextTop);
            int rString = (int) ((mRadius - (mTextMarginTop / 2)) * 0.8);
            float sweepAngle = 180 * textWidth / (3.1415f * rString);
            float startAngle = 90 - sweepAngle / 2;
            mRectF.set(mCenterX - rString, mCenterY - rString,
                    mCenterX + rString, mCenterY + rString);
            mPathString.reset();
            mPathString.arcTo(mRectF, 180 + startAngle, sweepAngle, true);
            canvas.drawTextOnPath(mTextTop, mPathString, 0, 0, mPaint);
        }
        // 五角心下文字
        if (mShowTitleCentre && !TextUtils.isEmpty(mTextCentre)) {
            mPaint.setTextSize(mTextSizeCentre * (mRadius / mTempR));
            mPaint.setLetterSpacing(mTextSpanCentre);
            Paint.FontMetrics fm = mPaint.getFontMetrics();
            float textHeight = (int) Math.ceil(fm.descent - fm.ascent);
            float textWidth = mPaint.measureText(mTextCentre);
            float poxy = outR * sin(72);
            canvas.save();
            canvas.translate(mCenterX, mCenterY);
            canvas.drawText(mTextCentre, (-textWidth / 2),
                    poxy + textHeight + mTextMarginCentre, mPaint);
            canvas.restore();
        }
        // 绘制下半部分字符
        if (mShowTitleBottom && !TextUtils.isEmpty(mTextBottom)) {
            mPaint.setTextSize(mTextSizeBottom * (mRadius / mTempR));
            mPaint.setLetterSpacing(mTextSpanBottom);
            float textWidth = mPaint.measureText(mTextBottom);
            int rString = (int) ((mRadius - (mTextMarginBottom / 2)) * 0.9);
            float sweepAngle = 180 * textWidth / (3.1415f * rString);
            float startAngle = 90 + sweepAngle / 2;
            mRectF.set(mCenterX - rString, mCenterY - rString + mTextMarginBottom,
                    mCenterX + rString, mCenterY + rString - mTextMarginBottom);
            mPathString.reset();
            mPathString.arcTo(mRectF, startAngle, -sweepAngle, true);
            canvas.drawTextOnPath(mTextBottom, mPathString, 0, 0, mPaint);
        }
        canvas.restore();
    }

    private Path getStarPath(float outR, float inR) {
        Path path = new Path();
        path.moveTo(outR * cos(0), outR * sin(0));
        path.lineTo(inR * cos(36), inR * sin(36));
        path.lineTo(outR * cos(72), outR * sin(72));
        path.lineTo(inR * cos(72 + 36), inR * sin(72 + 36));
        path.lineTo(outR * cos(72 * 2), outR * sin(72 * 2));
        path.lineTo(inR * cos(72 * 2 + 36), inR * sin(72 * 2 + 36));
        path.lineTo(outR * cos(72 * 3), outR * sin(72 * 3));
        path.lineTo(inR * cos(72 * 3 + 36), inR * sin(72 * 3 + 36));
        path.lineTo(outR * cos(72 * 4), outR * sin(72 * 4));
        path.lineTo(inR * cos(72 * 4 + 36), inR * sin(72 * 4 + 36));
        path.close();
        return path;
    }

    private static float cos(int num) {
        return (float) Math.cos(num * Math.PI / 180);
    }

    private static float sin(int num) {
        return (float) Math.sin(num * Math.PI / 180);
    }

    public void setColor(int color) {
        mColor = color;
        invalidate();
    }

    public void setStampAlpha(int alpha) {
        mAlpha = alpha;
        invalidate();
    }

    public void setBigOvalWidth(int width) {
        mBigOvalWidth = width;
        invalidate();
    }

    public void setShowStar(boolean showStar) {
        mShowStar = showStar;
        invalidate();
    }

    public String getTextTop() {
        return mTextTop;
    }

    public void setTextTop(String textTop) {
        this.mTextTop = textTop;
        invalidate();
    }

    public String getTextCentre() {
        return mTextCentre;
    }

    public void setTextCentre(String textCentre) {
        this.mTextCentre = textCentre;
        invalidate();
    }

    public String getTextBottom() {
        return mTextBottom;
    }

    public void setTextBottom(String textBottom) {
        this.mTextBottom = textBottom;
        invalidate();
    }

    public int getTextSizeTop() {
        return mTextSizeTop;
    }

    public void setTextSizeTop(int textSizeTop) {
        this.mTextSizeTop = textSizeTop;
        invalidate();
    }

    public int getTextSizeCentre() {
        return mTextSizeCentre;
    }

    public void setTextSizeCentre(int textSizeCentre) {
        this.mTextSizeCentre = textSizeCentre;
        invalidate();
    }

    public int getTextSizeBottom() {
        return mTextSizeBottom;
    }

    public void setTextSizeBottom(int textSizeBottom) {
        this.mTextSizeBottom = textSizeBottom;
        invalidate();
    }

    public int getTextMarginTop() {
        return mTextMarginTop;
    }

    public void setTextMarginTop(int textMarginTop) {
        this.mTextMarginTop = textMarginTop;
        invalidate();
    }

    public int getTextMarginCentre() {
        return mTextMarginCentre;
    }

    public void setTextMarginCentre(int textMarginCentre) {
        this.mTextMarginCentre = textMarginCentre;
        invalidate();
    }

    public int getTextMarginBottom() {
        return mTextMarginBottom;
    }

    public void setTextMarginBottom(int textMarginBottom) {
        this.mTextMarginBottom = textMarginBottom;
        invalidate();
    }

    public int getTextSpanTop() {
        return mTextSpanTop;
    }

    public void setTextSpanTop(int textSpanTop) {
        this.mTextSpanTop = textSpanTop;
        invalidate();
    }

    public int getTextSpanCentre() {
        return mTextSpanCentre;
    }

    public void setTextSpanCentre(int textSpanCentre) {
        this.mTextSpanCentre = textSpanCentre;
        invalidate();
    }

    public int getTextSpanBottom() {
        return mTextSpanBottom;
    }

    public void setTextSpanBottom(int textSpanBottom) {
        this.mTextSpanBottom = textSpanBottom;
        invalidate();
    }

    public boolean isShowTitleTop() {
        return mShowTitleTop;
    }

    public void setShowTitleTop(boolean showTitleTop) {
        mShowTitleTop = showTitleTop;
        invalidate();
    }

    public boolean isShowTitleCentre() {
        return mShowTitleCentre;
    }

    public void setShowTitleCentre(boolean showTitleCentre) {
        mShowTitleCentre = showTitleCentre;
        invalidate();
    }

    public boolean isShowTitleBottom() {
        return mShowTitleBottom;
    }

    public void setShowTitleBottom(boolean showTitleBottom) {
        mShowTitleBottom = showTitleBottom;
        invalidate();
    }
}
